package com.multipleimageselect.activities;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.asman.base.lib.utils.StatusBarUtil;
import com.jph.takephoto.R;
import com.multipleimageselect.adapters.CustomVideoSelectAdapter;
import com.multipleimageselect.helpers.Constants;
import com.multipleimageselect.models.Image;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;

/**
 * Created by Darshan on 4/18/2015.
 */
public class VideoSelectActivity extends HelperActivity {
    private ArrayList<Image> images;
    private String album;

    private TextView errorDisplay;

    private ProgressBar progressBar;
    private RecyclerView recyclerView;
    private CustomVideoSelectAdapter adapter;

    public int countSelected;

    private ContentObserver observer;
    private Handler handler;
    private Thread thread;
    public Toolbar toolbar;
    private final String[] projection = new String[]{
            MediaStore.Video.Media._ID,
            MediaStore.Video.Media.DISPLAY_NAME,
            MediaStore.Video.Media.DATA,
            MediaStore.Video.Media.SIZE,
            MediaStore.Video.Media.DURATION
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_select);
        StatusBarUtil.INSTANCE.setDarkModel(this);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//强制竖屏
        setView(findViewById(R.id.layout_image_select));

        toolbar = findViewById(R.id.toolbar);
        setSupportActionBarWithBack(toolbar, R.drawable.ic_back, v -> finish());
        toolbar.setTitle(countSelected + "/" + Constants.limit);

        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return;
        }
        album = intent.getStringExtra(Constants.INTENT_EXTRA_ALBUM);
        errorDisplay = findViewById(R.id.text_view_error);
        errorDisplay.setVisibility(View.INVISIBLE);

        progressBar = findViewById(R.id.progress_bar_image_select);
        recyclerView = findViewById(R.id.grid_view_image_select);
        recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
    }

    static class MyHandler extends Handler {
        WeakReference<VideoSelectActivity> weakReference;

        MyHandler(VideoSelectActivity activity) {
            weakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.PERMISSION_GRANTED:
                    weakReference.get().loadImages();
                    break;
                case Constants.FETCH_STARTED:
                    weakReference.get().progressBar.setVisibility(View.VISIBLE);
                    weakReference.get().recyclerView.setVisibility(View.INVISIBLE);
                    break;
                case Constants.FETCH_COMPLETED:
                    if (weakReference.get().adapter == null) {
                        weakReference.get().adapter = new CustomVideoSelectAdapter(weakReference.get().images);
                        weakReference.get().recyclerView.setAdapter(weakReference.get().adapter);
                        weakReference.get().progressBar.setVisibility(View.INVISIBLE);
                        weakReference.get().recyclerView.setVisibility(View.VISIBLE);
                    }
                    break;
                case Constants.ERROR:
                    weakReference.get().progressBar.setVisibility(View.INVISIBLE);
                    weakReference.get().errorDisplay.setVisibility(View.VISIBLE);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        handler = new MyHandler(this);
        observer = new ContentObserver(handler) {
            @Override
            public void onChange(boolean selfChange) {
                loadImages();
            }
        };
        getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, observer);
        checkPermission();
    }

    @Override
    protected void onStop() {
        super.onStop();

        stopThread();

        getContentResolver().unregisterContentObserver(observer);
        observer = null;

        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
            handler = null;
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.menu_item_add_image) {
            if (countSelected > 0)
                sendIntent();
            else
                Toast.makeText(this, "请选择图片", Toast.LENGTH_SHORT).show();
        } else if (item.getItemId() == android.R.id.home) {
            onBackPressed();
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_contextual_action_bar, menu);
        return super.onCreateOptionsMenu(menu);
    }

    public void toggleSelection(Image image) {
        if (!image.isSelected && countSelected >= Constants.limit) {
            Toast.makeText(
                    getApplicationContext(),
                    String.format(getString(R.string.limit_exceeded), Constants.limit),
                    Toast.LENGTH_SHORT)
                    .show();
            return;
        }
        image.isSelected = !image.isSelected;
        if (image.isSelected) {
            countSelected++;
        } else {
            countSelected--;
        }
        adapter.notifyItemChanged(images.indexOf(image));
    }

    private ArrayList<Image> getSelected() {
        ArrayList<Image> selectedImages = new ArrayList<>();
        for (int i = 0, l = images.size(); i < l; i++) {
            if (images.get(i).isSelected) {
                selectedImages.add(images.get(i));
            }
        }
        return selectedImages;
    }

    private void sendIntent() {
        Intent intent = new Intent();
        intent.putParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES, getSelected());
        setResult(RESULT_OK, intent);
        finish();
    }

    private void loadImages() {
        startThread(new ImageLoaderRunnable());
    }

    private class ImageLoaderRunnable implements Runnable {
        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            /*
            If the adapter is null, this is first duration this activity's view is
            being shown, hence send FETCH_STARTED message to initType progress bar
            while images are loaded from phone
             */
            if (adapter == null) {
                sendMessage(Constants.FETCH_STARTED);
            }

            File file;
            HashSet<Long> selectedImages = new HashSet<>();
            if (images != null) {
                Image image;
                for (int i = 0, l = images.size(); i < l; i++) {
                    image = images.get(i);
                    file = new File(image.path);
                    if (file.exists() && file.length() > 0 && image.isSelected) {
                        selectedImages.add(image.id);
                    }
                }
            }

            //获取视频
            Cursor cursor = getApplicationContext().getContentResolver()
                    .query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection,
                            null, null, MediaStore.Video.Media.DATE_ADDED);
            if (cursor == null) {
                sendMessage(Constants.ERROR);
                return;
            }

            /*
            In case this runnable is executed to onChange calling loadImages,
            using countSelected variable can result in a race condition. To avoid that,
            tempCountSelected keeps track of number of selected images. On handling
            FETCH_COMPLETED message, countSelected is assigned value of tempCountSelected.
             */
            int tempCountSelected = 0;
            ArrayList<Image> temp = new ArrayList<>(cursor.getCount());
            if (cursor.moveToLast()) {
                do {
                    if (Thread.interrupted()) {
                        return;
                    }

                    long id = cursor.getLong(cursor.getColumnIndex(projection[0]));
                    String name = cursor.getString(cursor.getColumnIndex(projection[1]));
                    String path = cursor.getString(cursor.getColumnIndex(projection[2]));
                    String size = cursor.getString(cursor.getColumnIndex(projection[3]));
                    String duration = cursor.getString(cursor.getColumnIndex(projection[4]));
                    boolean isSelected = selectedImages.contains(id);
                    if (isSelected) {
                        tempCountSelected++;
                    }

                    file = new File(path);
                    if (file.length() > 0) {
                        if (file.exists()) {
                            temp.add(new Image(id, name, path, size, duration, isSelected));
                        }
                    } else {
                        file.delete();
                    }

                } while (cursor.moveToPrevious());
            }
            cursor.close();

            if (images == null) {
                images = new ArrayList<>();
            }
            images.clear();
            images.addAll(temp);

            sendMessage(Constants.FETCH_COMPLETED, tempCountSelected);
        }
    }

    private void startThread(Runnable runnable) {
        stopThread();
        thread = new Thread(runnable);
        thread.start();
    }

    private void stopThread() {
        if (thread == null || !thread.isAlive()) {
            return;
        }

        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void sendMessage(int what) {
        sendMessage(what, 0);
    }

    private void sendMessage(int what, int arg1) {
        if (handler == null) {
            return;
        }

        Message message = handler.obtainMessage();
        message.what = what;
        message.arg1 = arg1;
        message.sendToTarget();
    }

    @Override
    protected void permissionGranted() {
        sendMessage(Constants.PERMISSION_GRANTED);
    }

    @Override
    protected void hideViews() {
        progressBar.setVisibility(View.INVISIBLE);
        recyclerView.setVisibility(View.INVISIBLE);
    }
}
